#include "MainWindow.h"
#include "ui_MainWindow.h"


#include <Defines.h>
#include <CampaignItem.h>
#include <ItemModel.h>
#include <ItemGroup.h>
#include <Item.h>



#include <XmlSerializer.h>
#include <FileHandler.h>


#include <QMessageBox>
#include <QFileDialog>
#include <QTreeView>
#include <QTimer>


namespace
{
QString NEW_CAMPAIGN_NAME = "New Campaign";
}



MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    FileHandler::installSerializer(new XmlSerializer());

    ui->setupUi(this);

}



MainWindow::~MainWindow()
{
    delete ui;
}



void MainWindow::closeEvent(QCloseEvent *e)
{
    on_actionQuit_triggered();

    QMainWindow::closeEvent(e);
}



void MainWindow::onRefreshTabs()
{
    for (int index = 0; index < ui->tabWidget->count(); index++)
    {
        QTreeView* view = qobject_cast<QTreeView*>(ui->tabWidget->widget(index));
        if (!view) continue;

        ItemModel* model = qobject_cast<ItemModel*>(view->model());
        if (!model) continue;

        if (!model->rootItem()) continue;

        ui->tabWidget->setTabText(index, model->rootItem()->name());

    }

    onBeginViewModify();
}



QTreeView* MainWindow::onCreateTab(const QString& name)
{
    QTreeView* view = new QTreeView(this);
    ui->tabWidget->addTab(view, name);
    ui->tabWidget->setCurrentWidget(view);

    onBeginViewModify();

    return view;
}



void MainWindow::onBeginViewModify()
{
    QTreeView* view = qobject_cast<QTreeView*>(ui->tabWidget->currentWidget());
    if (!view) return;

    QHeaderView* header = view->header();
    if (!header) return;

    header->setResizeMode(QHeaderView::ResizeToContents);

    QTimer::singleShot(0, this, SLOT(onEndViewModify()));

}



void MainWindow::onEndViewModify()
{
    QTreeView* view = qobject_cast<QTreeView*>(ui->tabWidget->currentWidget());
    if (!view) return;

    QHeaderView* header = view->header();
    if (!header) return;

    header->setResizeMode(QHeaderView::Interactive);
}



void MainWindow::on_actionSave_As_triggered()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), QDir::currentPath(), tr("Xml Files (*.xml)"));

    if (fileName.isEmpty()) return;

    int curr = ui->tabWidget->currentIndex();
    QString name = ui->tabWidget->tabText(curr);
    CampaignItem* item = CampaignItem::campaign(name);

    if (!item)
    {
        QMessageBox::information(0, tr("Invalid Campaign Name"), tr("Campaign does not exist: %1").arg(name));
        return;
    }

    if (!FileHandler::save(fileName, item))
    {
        QMessageBox::information(0, tr("Save Failed"), tr("Failed to save campaign!"));
    }

    item->setFilePath(fileName);
    item->setDirty(false);

}



void MainWindow::on_actionOpen_triggered()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Save As"), QDir::currentPath(), tr("Xml Files (*.xml)"));

    if (fileName.isEmpty()) return;

    CampaignItem* item = qobject_cast<CampaignItem*>(FileHandler::open(fileName));
    if (!item)
    {
        QMessageBox::information(0, tr("Open Failed"), tr("Failed to open campaign!"));
        return;
    }
    item->setFilePath(fileName);
    item->setDirty(false);
    connect(item, SIGNAL(sigRefresh()), this, SLOT(onRefreshTabs()));

    QTreeView* view = onCreateTab(item->name());

    view->setModel(item->model());

}



void MainWindow::on_actionNew_triggered()
{
    CampaignItem* item = CampaignItem::add(NEW_CAMPAIGN_NAME);
    item->setDirty(true);
    connect(item, SIGNAL(sigRefresh()), this, SLOT(onRefreshTabs()));

    QTreeView* view = onCreateTab(item->name());

    view->setModel(item->model());
}



void MainWindow::on_actionSave_triggered()
{
    int curr = ui->tabWidget->currentIndex();
    QString name = ui->tabWidget->tabText(curr);
    CampaignItem* item = CampaignItem::campaign(name);

    if (!item)
    {
        QMessageBox::information(0, tr("Invalid Campaign Name"), tr("Campaign does not exist: %1").arg(name));
        return;
    }

    QString fileName = item->filePath();
    if (!QFile::exists(fileName))
    {
        on_actionSave_As_triggered();
        return;
    }

    if (!FileHandler::save(fileName, item))
    {
        QMessageBox::information(0, tr("Save Failed"), tr("Failed to save campaign!"));
    }

    item->setDirty(false);
}



void MainWindow::on_tabWidget_tabCloseRequested(int index)
{
    QString name = ui->tabWidget->tabText(index);
    CampaignItem* item = CampaignItem::take(name);

    if (!item || !item->isDirty())
    {
        ui->tabWidget->removeTab(index);
        return;
    }


    if (QMessageBox::question(0,
                              tr("Save Changed?"),
                              tr("Campaign has changed. Do you want to save it?"),
                              QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
    {
        ui->tabWidget->removeTab(index);
        return;
    }

    on_actionSave_triggered();
    ui->tabWidget->removeTab(index);

}



void MainWindow::on_actionAdd_Group_triggered()
{
    QTreeView* view = qobject_cast<QTreeView*>(ui->tabWidget->currentWidget());

    if (!view) return;

    ItemModel* model = qobject_cast<ItemModel*>(view->model());
    if (!model) return;

    model->insertRow(0, QModelIndex());
    onBeginViewModify();
}



void MainWindow::on_actionAdd_Item_triggered()
{

    QTreeView* view = qobject_cast<QTreeView*>(ui->tabWidget->currentWidget());

    if (!view) return;

    ItemModel* model = qobject_cast<ItemModel*>(view->model());
    if (!model) return;

    QModelIndex index = view->currentIndex();

    if (!index.isValid()) return; // can't add item to root
    if (index.parent().isValid()) index = index.parent();

    model->insertRow(0, index);
    onBeginViewModify();
}



void MainWindow::on_actionBegin_Edit_triggered()
{
    QTreeView* view = qobject_cast<QTreeView*>(ui->tabWidget->currentWidget());

    if (!view) return;

    QModelIndex index = view->currentIndex();
    if (!index.isValid()) return;

    view->edit(index);
}



void MainWindow::on_actionClose_Current_triggered()
{
    int index = ui->tabWidget->currentIndex();
    on_tabWidget_tabCloseRequested(index);
}



void MainWindow::on_actionQuit_triggered()
{
    int tabs = ui->tabWidget->count();
    for (int index = 0; index < tabs; index++)
    {
        on_tabWidget_tabCloseRequested(index);
    }

    close();
}



void MainWindow::on_actionRename_triggered()
{
    ui->tabWidget->onBeginRename(ui->tabWidget->currentIndex());
}

void MainWindow::on_actionRefresh_triggered()
{
    onBeginViewModify();
}
